package CalendarComponents;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.LineBorder;

import Managers.Appointment;
import Managers.CalendarManager;
import Managers.Category;
import Managers.Day;
import Managers.ICMObservable;
import Managers.ICMObserver;
import calendar.MainWindow;


@SuppressWarnings("serial")
public abstract class DayView extends JPanel implements ICMObserver
{
	private BusyMeter bm;
	private FilterBox fb;
	private PopupMenu popup;
	private Day day;
	private JTextField jta;
	

	
	public DayView(Day d, int width, int height)
	{
		//get the observable
		ICMObservable io = CalendarManager.getInstance();
		
		//add this observer to the observable
		io.addObserver(this);
		
		//set day
		day = d;
		

		//setup component
		this.setLayout(new BorderLayout());
		
		this.addMouseListener(new Click());

		this.setBackground(Color.WHITE);
		
		//create Title
		jta = new JTextField();
		jta.setText(day != null ? day.toString() : "" );
		jta.setBorder(null);
		this.add(jta, BorderLayout.NORTH);
		
		//Create FilterBox
		fb = new FilterBox();
		fb.addMouseListener(new Click());
		fb.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		
		//make the Filterbox Scrollable
		JScrollPane jsp = new JScrollPane(fb);
		jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		jsp.setPreferredSize(new Dimension(width-5,height - jta.getHeight() - 10));
		this.add(jsp, BorderLayout.CENTER);
		
		//Create BusyMeter
		bm = new BusyMeter(5, height);
		
		//Create PopupMenu
		popup = new PopupMenu(this);
		emph();
		this.add(bm, BorderLayout.EAST);
	}
		
	
	class Click implements MouseListener
	{

		@Override
		public void mouseClicked(MouseEvent e)
		{

			if(e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
			{
				Appointment ax = (Appointment)((FilterBox)e.getSource()).getSelectedValue();
				//create Properties dialog
				PropertiesDialog pd = new PropertiesDialog(MainWindow.getMainWindow(), ax);
				//show it
				pd.setVisible(true);
				//get the appointment
				Appointment er = pd.getAppointment();
							
				if(er == null)
				{
					return;//most likly a close
				}
				else
				{
					if(pd.getAppointment().isDeleted())
					{
						CalendarManager.DeleteAppointment(pd.getOldAppointment());//remove it from old day
					}
					else
					{
						CalendarManager.DeleteAppointment(pd.getOldAppointment());//remove it from old day
						CalendarManager.AddAppointment(day, er);//add it to new day.
					}
				}
			}
			
		}

		@Override
		public void mousePressed(MouseEvent e) {
			if (e.isPopupTrigger()) { 
				popup.getMenu().show(e.getComponent(), e.getX(), e.getY());//show context menu
			} 
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			if (e.isPopupTrigger()) { 
	    		popup.getMenu().show(e.getComponent(), e.getX(), e.getY()); //show context menu
	    	}
		}

		@Override
		public void mouseEntered(MouseEvent e) {
		}

		@Override
		public void mouseExited(MouseEvent e) {
		}
		
	}

	//folowing are a few "helper" methods 
	public Day getDay() {
		return day;
	}

	public void setDay(Day day) {
		this.day = day;
	}

	public void emph()
	{
		if(day != null)
		{
			if(day.isToday())
			{
				Color c = new Color(0xE0E0E0);
				this.setBorder(new LineBorder(c));
				this.fb.setBackground(c);
				this.jta.setBackground(c);
			}
			else
			{
				this.setBorder(null);
				this.fb.setBackground(Color.WHITE);
				this.jta.setBackground(Color.WHITE);
			}
		}
	}
	
	public void setTitle(String s)
	{
		jta.setText(s);
	}
	
	public FilterBox getFilterBox()
	{
		return fb;
	}
	
	public void UpdateBusyBox()
	{
		bm.setMeter(fb.getNumberOfElements());
	}
	
	public void updateLookAndFeel(Day d)
	{
		setDay(d);
		emph();
		setTitle(getDay().toString());
		getFilterBox().setModel(getDay().getModel());
		UpdateBusyBox();
		getFilterBox().repaint();	
	}
	
	public void updateLookAndFeel(Day d, Category[] filter)
	{
		setDay(d);
		emph();
		setTitle(getDay().toString());
		getFilterBox().setModel(getDay().getModel(filter));
		UpdateBusyBox();
		getFilterBox().repaint();	
	}
	
	
	//abstract method anything extending this class will have to implement this method.
	@Override
	public abstract void Update();
}
